package com.ruoyi.fire.service.impl;

import java.util.*;
import java.util.concurrent.Executor;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.ResponseEntityInfo;
import com.ruoyi.common.enums.DeviceCategory;
import com.ruoyi.common.enums.PushStatus;
import com.ruoyi.common.enums.RequestMapper;
import com.ruoyi.common.enums.UnitType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.*;
import com.ruoyi.fire.domain.*;
import com.ruoyi.fire.service.IDGatewayMessageService;
import com.ruoyi.fire.service.IDWaterMessageService;
import com.ruoyi.fire.service.ITDeviceService;
import com.ruoyi.system.service.ISysDictDataService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.fire.mapper.TUnitMapper;
import com.ruoyi.fire.service.ITUnitService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 单位信息Service业务层处理
 *
 * @author ruoyi
 * @date 2025-11-02
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TUnitServiceImpl extends ServiceImpl<TUnitMapper, TUnit> implements ITUnitService {
    @Autowired
    private TUnitMapper tUnitMapper;

    private final RequestService requestService;
    // 添加线程池注入
    private final Executor threadPoolTaskExecutor;
    @Autowired
    private ITDeviceService deviceService;
    private final ISysDictDataService dictDataService;
    private final IDGatewayMessageService gatewayMessageService;
    private final IDWaterMessageService waterMessageService;

    // 水池/水箱
    private static final Set<String> WATER_POOL_TANK_TYPES = new HashSet<>(Arrays.asList("1", "4"));
    // 消火栓
    private static final Set<String> HYDRANT_TYPES = new HashSet<>(Collections.singletonList("2"));
    // 喷淋
    private static final Set<String> SPRINKLER_TYPES = new HashSet<>(Collections.singletonList("3"));


    /**
     * 查询单位信息
     *
     * @param id 单位信息主键
     * @return 单位信息
     */
    @Override
    public TUnit selectTUnitById(String id) {
        TUnit unit = tUnitMapper.selectTUnitById(id);
        if (unit != null){

        }
        return unit;
    }

    /**
     * 查询单位信息列表
     *
     * @param tUnit 单位信息
     * @return 单位信息
     */
    @Override
    public List<TUnit> selectTUnitList(TUnit tUnit) {
        return tUnitMapper.selectTUnitList(tUnit);
    }

    /**
     * 新增单位信息
     *
     * @param tUnit 单位信息
     * @return 结果
     */
    @Override
    public boolean insertTUnit(TUnit tUnit) {

        boolean isNetworkedUnit = UnitType.NETWORKED_UNITS.getCode().equals(tUnit.getUnitType());

        if (isNetworkedUnit) {
            tUnit.setPushStatus(PushStatus.PUSH_FAILED.getCode());
        } else {
            tUnit.setPushStatus(PushStatus.NOT_PUSHED.getCode());
        }

        Long userId = SecurityUtils.getUserId();
        String username = SecurityUtils.getUsername();
        tUnit.setCreateBy(username);
        tUnit.setCreateTime(DateUtils.getNowDate());
        tUnit.setCreateUserId(userId);

        boolean result = save(tUnit);
        if (result && isNetworkedUnit) {
            // 提交至线程池异步处理推送逻辑
            threadPoolTaskExecutor.execute(() -> {
                try {
                    Map<String, Object> unitMap = ConvertToMap.convertObjectToMap(tUnit);
                    unitMap.remove("id");
                    ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(RequestMapper.NEW_NETWORKING_UNITS, unitMap);

                    TUnit unit = JSON.parseObject(responseEntityInfo.getData().toString(), TUnit.class);

                    LambdaUpdateWrapper<TUnit> updateWrapper = Wrappers.lambdaUpdate(TUnit.class)
                            .eq(TUnit::getId, tUnit.getId())
                            .set(TUnit::getPushStatus, PushStatus.PUSH_SUCCESSFUL.getCode())
                            .set(TUnit::getUnitId, unit.getId());
                    update(updateWrapper);
                } catch (Exception e) {
                    log.error("推送联网单位失败: unitId={}, error={}", tUnit.getId(), e.getMessage(), e);

                    // 更新推送状态为失败
                    LambdaUpdateWrapper<TUnit> failUpdateWrapper = Wrappers.lambdaUpdate(TUnit.class)
                            .eq(TUnit::getId, tUnit.getId())
                            .set(TUnit::getPushStatus, PushStatus.PUSH_FAILED.getCode());
                    update(failUpdateWrapper);
                }
            });
        }
        return result;
    }

    /**
     * 修改单位信息
     *
     * @param tUnit 单位信息
     * @return 结果
     */
    @Override
    public int updateTUnit(TUnit tUnit) {
        boolean isNetworkedUnit = UnitType.NETWORKED_UNITS.getCode().equals(tUnit.getUnitType());

        // 设置推送状态
        if (!isNetworkedUnit) {
            tUnit.setPushStatus(PushStatus.NOT_PUSHED.getCode());
        }

        tUnit.setUpdateTime(DateUtils.getNowDate());
        int result = tUnitMapper.updateTUnit(tUnit);

        if (result > 0 && isNetworkedUnit) {
            // 提交至线程池异步处理推送逻辑
            threadPoolTaskExecutor.execute(() -> {
                try {
                    RequestMapper requestMapper = tUnit.getUnitId() != null ? RequestMapper.MODIFY_THE_NETWORKING_UNIT : RequestMapper.NEW_NETWORKING_UNITS;
                    Map<String, Object> unitMap = ConvertToMap.convertObjectToMap(tUnit);
                    if (tUnit.getUnitId() != null) {
                        unitMap.put("id", tUnit.getUnitId());
                    } else {
                        unitMap.remove("id");
                    }

                    ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(requestMapper, unitMap);

                    TUnit unit = JSON.parseObject(responseEntityInfo.getData().toString(), TUnit.class);

                    LambdaUpdateWrapper<TUnit> updateWrapper = Wrappers.lambdaUpdate(TUnit.class)
                            .eq(TUnit::getId, tUnit.getId())
                            .set(TUnit::getPushStatus, PushStatus.PUSH_SUCCESSFUL.getCode())
                            .set(TUnit::getUnitId, unit.getId());
                    update(updateWrapper);
                } catch (Exception e) {
                    log.error("推送联网单位失败: unitId={}, error={}", tUnit.getId(), e.getMessage(), e);

                    // 更新推送状态为失败
                    LambdaUpdateWrapper<TUnit> failUpdateWrapper = Wrappers.lambdaUpdate(TUnit.class)
                            .eq(TUnit::getId, tUnit.getId())
                            .set(TUnit::getPushStatus, PushStatus.PUSH_FAILED.getCode());
                    update(failUpdateWrapper);
                }
            });
        }
        return result;
    }

    /**
     * 批量删除单位信息
     *
     * @param ids 需要删除的单位信息主键
     * @return 结果
     */
    @Override
    public int deleteTUnitByIds(String[] ids) {
        return tUnitMapper.deleteTUnitByIds(ids);
    }

    /**
     * 删除单位信息信息
     *
     * @param id 单位信息主键
     * @return 结果
     */
    @Override
    public int deleteTUnitById(String id) {
        return tUnitMapper.deleteTUnitById(id);
    }

    /**
     * 同步单位信息
     *
     * @param id 单位信息主键
     * @return 结果
     */
    @Override
    public boolean pushTUnit(String id) {
        TUnit unit = getById(id);
        if (unit == null) {
            log.warn("单位信息不存在，id={}", id);
            return false;
        }

        boolean isNew = unit.getUnitId() == null || unit.getUnitId().equals("");

        doPush(isNew, unit);

        return true;
    }


    private void doPush(boolean isNew, TUnit unit) {
        String requestType = isNew ? "新增联网单位" : "修改联网单位";
        log.info("开始{}推送，unitId={}", requestType, unit.getId());

        Map<String, Object> unitMap = ConvertToMap.convertObjectToMap(unit);
        if (isNew) {
            unitMap.remove("id");
        } else {
            unitMap.put("id", unit.getUnitId());
        }

        RequestMapper mapper = isNew ? RequestMapper.NEW_NETWORKING_UNITS : RequestMapper.MODIFY_THE_NETWORKING_UNIT;
        ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(mapper, unitMap);

        if (responseEntityInfo.getErrno() != 0) {
            log.error("{}推送失败，unitId={}, error={}", requestType, unit.getId(), responseEntityInfo.getErrmsg());

            // 推送失败
            LambdaUpdateWrapper<TUnit> failUpdateWrapper = Wrappers.lambdaUpdate(TUnit.class)
                    .eq(TUnit::getId, unit.getId())
                    .set(TUnit::getPushStatus, PushStatus.PUSH_FAILED.getCode());

            update(failUpdateWrapper);
            throw new ServiceException(responseEntityInfo.getErrmsg());
        }

        TUnit unitResult = JSON.parseObject(responseEntityInfo.getData().toString(), TUnit.class);

        LambdaUpdateWrapper<TUnit> updateWrapper = Wrappers.lambdaUpdate(TUnit.class)
                .eq(TUnit::getId, unit.getId())
                .set(TUnit::getPushStatus, PushStatus.PUSH_SUCCESSFUL.getCode())
                .set(TUnit::getUnitId, unitResult.getId());

        update(updateWrapper);

        log.info("{}推送成功，unitId={}", requestType, unit.getId());
    }

    /**
     * 查询单位信息列表
     *
     * @param unit 单位信息
     * @return 单位集合
     */
    @Override
    public List<TUnit> selectTDeviceListCard(TUnit unit) {
        List<TUnit> tUnits = selectTUnitList(unit);
        if (CollectionUtils.isEmpty(tUnits)) {
            return tUnits;
        }

        List<String> unitIds = tUnits.stream().map(TUnit::getId).collect(Collectors.toList());
        List<TDevice> deviceList = deviceService.list(new LambdaQueryWrapper<TDevice>().in(TDevice::getUnitId, unitIds));

        if (CollectionUtils.isEmpty(deviceList)) {
            for (TUnit tUnit : tUnits) {
                tUnit.setDeviceList(Collections.emptyList());
            }
            return tUnits;
        }

        // 批量获取网关和水表消息
        Set<String> gatewayDeviceNos = deviceList.stream()
                .filter(d -> DeviceCategory.GATEWAY.getCode().equals(d.getDeviceCategory()))
                .map(TDevice::getDeviceCode)
                .collect(Collectors.toSet());

        Set<String> waterDeviceNos = deviceList.stream()
                .filter(d -> DeviceCategory.WATER.getCode().equals(d.getDeviceCategory()))
                .map(TDevice::getDeviceCode)
                .collect(Collectors.toSet());

        Map<String, DGatewayMessage> gatewayMsgMap = new HashMap<>();
        if (!gatewayDeviceNos.isEmpty()) {
            List<DGatewayMessage> gatewayMessages = gatewayMessageService.selectLastOneByDeviceNos(gatewayDeviceNos);
            gatewayMsgMap = gatewayMessages.stream()
                    .collect(Collectors.toMap(DGatewayMessage::getSN, Function.identity(), (a, b) -> a));
        }

        Map<String, DWaterMessage> waterMsgMap = new HashMap<>();
        if (!waterDeviceNos.isEmpty()) {
            List<DWaterMessage> waterMessages = waterMessageService.selectLastOneByDeviceNos(waterDeviceNos);
            waterMsgMap = waterMessages.stream()
                    .collect(Collectors.toMap(DWaterMessage::getSN, Function.identity(), (a, b) -> a));
        }

        // 构建类型到标识码的映射
        Map<String, String> typeToDeviceCodeMap = new HashMap<>();
        WATER_POOL_TANK_TYPES.forEach(type -> typeToDeviceCodeMap.put(type, "A1"));
        HYDRANT_TYPES.forEach(type -> typeToDeviceCodeMap.put(type, "A2"));
        SPRINKLER_TYPES.forEach(type -> typeToDeviceCodeMap.put(type, "A3"));

        // 设置设备最新值
        for (TDevice device : deviceList) {
            try {
                if (DeviceCategory.GATEWAY.getCode().equals(device.getDeviceCategory())) {
                    DGatewayMessage msg = gatewayMsgMap.get(device.getDeviceCode());
                    if (msg != null) {
                        device.setLatestValue(msg.getPS());
                    }
                } else {
                    DWaterMessage waterMsg = waterMsgMap.get(device.getDeviceCode());
                    if (waterMsg == null || CollectionUtils.isEmpty(waterMsg.getWaterDeviceMessages())) {
                        continue;
                    }

                    String targetDeviceType = typeToDeviceCodeMap.get(device.getDeviceName());
                    if (targetDeviceType == null) {
                        continue;
                    }

                    Optional<DWaterDeviceMessage> matchedMsgOpt = waterMsg.getWaterDeviceMessages().stream()
                            .filter(m -> targetDeviceType.equals(m.getDevice()))
                            .findFirst();

                    if (matchedMsgOpt.isPresent()) {
                        device.setLatestValue(matchedMsgOpt.get().getField4());
                    }
                }
            } catch (Exception e) {
                log.warn("未能获取设备的最新值: {}", device.getDeviceCode(), e);
            }
        }

        // 按 unitId 分组设备
        Map<String, List<TDevice>> groupedDevices = deviceList.stream()
                .collect(Collectors.groupingBy(TDevice::getUnitId));

        // 填充每个 TUnit 的设备列表
        for (TUnit tUnit : tUnits) {
            tUnit.setDeviceList(groupedDevices.getOrDefault(tUnit.getId(), Collections.emptyList()));
        }

        return tUnits;
    }

    /**
     * 远程删除单位信息
     *
     * @param unitId 单位信息主键
     * @return 删除结果
     */
    @Override
    public boolean remoteDeletion(String unitId) {
        TUnit unit = getById(unitId);
        if (StringUtils.isNotNull(unit)) {
            Map<String, Object> params = new HashMap<>();
            params.put("id", unit.getUnitId());
            ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(RequestMapper.UNIT_DELETE, params);

            if (responseEntityInfo.getErrno() == 0) {
                LambdaUpdateWrapper<TUnit> updateWrapper = Wrappers.lambdaUpdate(TUnit.class);
                updateWrapper.set(TUnit::getUnitId, "");
                updateWrapper.set(TUnit::getPushStatus, PushStatus.NOT_PUSHED.getCode());
                updateWrapper.eq(TUnit::getId, unit.getId());
                update(updateWrapper);
            }
            throw new ServiceException("远程删除失败： " + responseEntityInfo.getErrmsg());
        }
        return true;
    }

    /**
     * 删除单位信息
     *
     * @param unitId 单位信息主键
     * @return 删除结果
     */
    @Override
    public int removeByUnitId(String unitId) {
        TUnit unit = getById(unitId);
        if (StringUtils.isNotNull(unit) && StringUtils.isNotEmpty(unit.getUnitId())) {
            Map<String, Object> params = new HashMap<>();
            params.put("id", unit.getUnitId());
            ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(RequestMapper.UNIT_DELETE, params);

            if (responseEntityInfo.getErrno() == 0) {
                removeById(unitId);
            } else {
                throw new ServiceException("远程删除失败： " + responseEntityInfo.getErrmsg());
            }
        }
        return 0;
    }
}
